#include "hal.h"


#if (HAL_USE_I2C > 0)

HAL_ERROR i2c_init(I2C_DRIVER *i2cp)
{
	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT(i2cp != 0);

	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_init(i2cp);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);	

	return ret;
	
}


HAL_ERROR i2c_start(I2C_DRIVER *i2cp, I2C_CONFIG *config)
{
	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT((i2cp != 0) && (config != 0));

	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	i2cp->config = config;
	ret = i2c_lld_start(i2cp, config);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	return ret;
  
}

HAL_ERROR i2c_stop(I2C_DRIVER *i2cp)
{
	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT(i2cp != 0);
 
	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_stop(i2cp);
	
	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	return ret;
}


HAL_ERROR i2c_master_transmit(I2C_DRIVER *i2cp,
                                 RAW_U32 dev_addr,
                                 RAW_U8 *tx_buf, RAW_U32 tx_bytes,
                                 RAW_U8 *rx_buf, RAW_U32 rx_bytes,
                                 RAW_U32 timeout)
{

	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT((i2cp != 0) && (dev_addr != 0U) && (tx_bytes > 0U) && (tx_buf != 0));
	          
	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_master_transmit(i2cp, dev_addr, tx_buf, tx_bytes, rx_buf, rx_bytes, timeout);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	return ret;
  
}


HAL_ERROR i2c_mem_write(I2C_DRIVER *i2cp,
                             RAW_U32 dev_addr, RAW_U16 mem_address, 
                             RAW_U16 mem_size, RAW_U8 *tx_buf, 
                             RAW_U32 tx_bytes, RAW_U8 *rx_buf, 
                             RAW_U32 rx_bytes, RAW_U32 timeout)
{

	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT((i2cp != 0) && (dev_addr != 0U) && (tx_bytes > 0U) && (tx_buf != 0));
	          
	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_mem_write(i2cp, dev_addr, mem_address, mem_size, tx_buf, tx_bytes, rx_buf, rx_bytes, timeout);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	return ret;
  
}

HAL_ERROR i2c_master_receive(I2C_DRIVER *i2cp,
								  RAW_U32 dev_addr,
								  RAW_U8 *rx_buf, RAW_U32 rx_bytes,
								  RAW_U32 timeout)
{
	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT((i2cp != 0) && (dev_addr != 0U) &&
	       (rx_bytes > 0U) && (rx_buf != 0));

	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_master_receive(i2cp, dev_addr, rx_buf, rx_bytes, timeout);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	return ret;
}


HAL_ERROR i2c_mem_receive(I2C_DRIVER *i2cp,
								RAW_U32 dev_addr, RAW_U16 mem_address, 
								RAW_U16 mem_size, RAW_U8 *rx_buf, 
								RAW_U32 rx_bytes, RAW_U32 timeout)
{
	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT((i2cp != 0) && (dev_addr != 0U) &&
	       (rx_bytes > 0U) && (rx_buf != 0));

	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_mem_receive(i2cp, dev_addr, mem_address, mem_size, rx_buf, rx_bytes, timeout);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	return ret;
}


HAL_ERROR i2c_deinit(I2C_DRIVER *i2cp)
{
	HAL_ERROR ret;
	RAW_OS_ERROR mutex_error;
	
	RAW_ASSERT(i2cp != 0);

	mutex_error = raw_mutex_get(&i2cp->i2cp_lock, RAW_WAIT_FOREVER);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);
	
	ret = i2c_lld_deinit(i2cp);

	mutex_error = raw_mutex_put(&i2cp->i2cp_lock);
	RAW_ASSERT(mutex_error == RAW_SUCCESS);

	return ret;
	
}


#endif 


